//
// winter - Direct2D GUI framework.
// Copyright (C) 2009 Aleksandar Dezelin 
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#ifndef WINTER_ASSERT_H
#define WINTER_ASSERT_H

#pragma once
#include <intrin.h>
#include <stdlib.h>
#include <string>
#include <Windows.h>

namespace winter {
namespace platform {

std::wstring winter_create_error_message(const std::wstring& file, const std::wstring& line, 
  const std::wstring& failed_condition) {
  return L"CONDITION: " + failed_condition + L"\n" + file + L":" + line;
}

void winter_show_error(const std::wstring& file, const std::wstring& line, 
  const std::wstring& failed_condition) {
  std::wstring msg = winter_create_error_message(file, line, failed_condition);
  ::MessageBox(NULL, msg.c_str(), L"ASSERTION FAILED", MB_OK | MB_ICONERROR);
}

}
}

#define __STRING__(x) #x
#define __STRINGIZE__(x)  __STRING__(x)

#define __WIDEN2__(x) L##x
#define __WIDEN__(x) __WIDEN2__(x)

#define WINTER_ENSURE(x) \
if(!(x)) { \
  std::string error_message = "Condition \'" + std::string(#x) + "\' failed"; \
  throw std::runtime_error(error_message); \
}

#if defined(_DEBUG)

#define WINTER_ASSERT(x) \
if(!(x)) { \
  winter::platform::winter_show_error(__WIDEN__(__FILE__), \
    __WIDEN__(__STRINGIZE__(__LINE__)), __WIDEN__(#x)); \
  __debugbreak(); \
}

#define WINTER_VERIFY(x) WINTER_ASSERT(x)

#else

#define WINTER_ASSERT(x) ((void)(x))
#define WINTER_VERIFY(x) WINTER_ASSERT(x)

#endif

#endif // WINTER_ASSERT_H
